package log

import "sync"

/* //* 日志管理器实现，提供日志记录器的注册、获取和管理功能，支持读写锁保证并发安全 */

/*
日志管理器
*/

// * 日志管理器
type Manager struct {
	loggers map[string]Logger
	mu      sync.RWMutex
	/*
		普通互斥锁对所有操作（读 / 写）一视同仁，同一时间只允许一个 goroutine 访问资源；
		而读写锁区分 “读操作” 和 “写操作”，允许多个读操作并发访问，仅对写操作进行排他性限制
	*/
}

// 创建日志管理器
func NewManager() *Manager {
	return &Manager{
		loggers: make(map[string]Logger),
	}
}

// 获取日志记录器
func (m *Manager) GetLogger(name string) Logger {
	// 解决读写锁使用问题，读锁不允许修改
	m.mu.Lock()
	logger, exists := m.loggers[name]
	m.mu.Unlock()
	if exists {
		return logger
	}
	m.mu.Lock()
	defer m.mu.Unlock()
	// 再次检查，可能等待过程中以及创建了
	if logger, exists := m.loggers[name]; exists {
		return logger
	}
	// 如果不存在，新建一个日志记录器
	logger = NewStdLogger(LevelInfo)
	m.loggers[name] = logger
	// *StdLogger 实现了Logger接口的函数，这一点很重要，在这里，能否用接口指向目标位置，就看指向的目标是否实现
	// 相对应的，如果使用的StdLogger 那么这里返回一个指针就不行
	return logger
}

// 设置日志记录器
func (m *Manager) SetLogger(name string, logger Logger) {
	m.mu.Lock()
	defer m.mu.Unlock()
	m.loggers[name] = logger
}

// 移除日志记录器
func (m *Manager) RemoveLogger(name string) {
	m.mu.Lock()
	defer m.mu.Unlock()
	delete(m.loggers, name)
}

// 设置所有日志记录器的级别
func (m *Manager) SetLevel(level Level) {
	m.mu.Lock()
	defer m.mu.Unlock()
	for _, logger := range m.loggers {
		logger.SetLevel(level)
	}
}
